package Algorithm;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;

public class SearchImpl implements Search
{
    static final String DB_URL = "jdbc:mysql://39.105.0.127:3306/booksite?characterEncoding=utf-8";
    static final String USER = "root";
    static final String PASS = "123456";

    private DataHolder dataHolder;

    public List<String> getSql_search_list() {
        return dataHolder.getSql_search_list();
    }

    public void setSql_search_list(List<String> sql_search_list) {
        dataHolder.setSql_search_list(sql_search_list);
    }

    public Map<String, String> getSearch_list_map() {
        return dataHolder.getSearch_list_map();
    }

    public void setSearch_list_map(Map<String, String> search_list_map) {
        dataHolder.setSearch_list_map(search_list_map);
    }

    public List<String> getFinal_search_list() {
        return dataHolder.getFinal_search_list();
    }

    public void setFinal_search_list(List<String> final_search_list) {
        dataHolder.setFinal_search_list(final_search_list);
    }

    @Override
    public List<String> search(String searchContent)
    {
        dataHolder = new DataHolder();  //内部类
        getSqlSearchResult(searchContent);
        getSearchMap(searchContent);
        getSearchList();
        return getFinal_search_list();
    }



    //得到最终的搜索列表，存储在final_search_list中
    public  List<String> getSearchList()
    {
        for (Map.Entry<String, String> entry : getSearch_list_map().entrySet())
        {
            getFinal_search_list().add(entry.getKey()+ ":" + entry.getValue());
        }
        return getFinal_search_list();
    }

    //根据搜索输入的内容返回 图书id+书名 列表，储存在sql_search_list中
    public  List<String> getSqlSearchResult(String search)
    {
        Connection connection = null;
        Statement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(DB_URL,USER,PASS);
            statement = connection.createStatement();
            String sql = "select book_id, book_name from doe_book where book_name like\'%" + search + "%\';";
            ResultSet resultSet = statement.executeQuery(sql);
            System.out.println(sql);
            while (resultSet.next())
            {
                String book_id = resultSet.getString("book_id");
                String book_name = resultSet.getString("book_name");
                getSql_search_list().add(book_id + "," + book_name);
            }
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e){
            e.printStackTrace();
        }
        return getSql_search_list();
    }

    //根据sql_search_list中的 图书id+书名 列表，返回按照jaccardSimilarity排序的Map，key是bookID,value是jaccardSimilarity，储存在search_list_map中
    public  Map<String, String> getSearchMap(String search)
    {
        for (String book : getSql_search_list()){
            String[] book_info = book.split(",");
            String book_id = book_info[0];
            String book_name = book_info[1];
            int jaccard2int = Math.round(jaccard(search,book_name));
            String jaccard_value = String.valueOf(jaccard2int);
            if (jaccard2int>0)
                getSearch_list_map().put(book_id,jaccard_value);
        }
        setSearch_list_map(SortMap.sortMapByValueDesc(getSearch_list_map()));
        return getSearch_list_map();
    }

    //计算两个字符串的jaccardSimilarity
    public  float jaccard(String s, String t)
    {
        String[] sSplit=s.split("");
        String[] tSplit=t.split("");

        //calculate intersection
        List<String> intersection=new ArrayList<String>();
        for(int i=0;i<sSplit.length;i++)
        {
            for(int j=0;j<tSplit.length;j++)
            {
                if(!intersection.contains(sSplit[i]))       //no duplicate
                    if(sSplit[i].equals(tSplit[j]))         //has intersection
                    {
                        intersection.add(sSplit[i]);
                        break;
                    }
            }
        }

        //calculate union
        List<String> union=new ArrayList<String>();
        if(sSplit.length>tSplit.length)
        {
            //calculate big tupple first
            for(int i=0;i<sSplit.length;i++)
                if(!union.contains(sSplit[i]))
                    union.add(sSplit[i]);
            for(int i=0;i<tSplit.length;i++)
                if(!union.contains(tSplit[i]))
                    union.add(tSplit[i]);
        }
        else
        {
            for(int i=0;i<tSplit.length;i++)
                if(!union.contains(tSplit[i]))
                    union.add(tSplit[i]);
            for(int i=0;i<sSplit.length;i++)
                if(!union.contains(sSplit[i]))
                    union.add(sSplit[i]);

        }
        return ((float)intersection.size())/((float)union.size()) * 100;
    }

    class DataHolder
    {
        private List<String> sql_search_list = new ArrayList<>();
        private Map<String, String> search_list_map = new TreeMap<>();
        private List<String> final_search_list = new ArrayList<>();

        public List<String> getSql_search_list() {
            return sql_search_list;
        }

        public void setSql_search_list(List<String> sql_search_list) {
            this.sql_search_list = sql_search_list;
        }

        public Map<String, String> getSearch_list_map() {
            return search_list_map;
        }

        public void setSearch_list_map(Map<String, String> search_list_map) {
            this.search_list_map = search_list_map;
        }

        public List<String> getFinal_search_list() {
            return final_search_list;
        }

        public void setFinal_search_list(List<String> final_search_list) {
            this.final_search_list = final_search_list;
        }
    }

}
